package com.gaofans.vertx.boot.common.verticle;

import io.vertx.core.Vertx;
import io.vertx.core.spi.VerticleFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.SmartLifecycle;

import java.util.Collection;

/**
 * @author GaoFans
 */
public class MainVerticleLifecycle implements SmartLifecycle {

    private volatile Vertx vertx;
    private VerticleFactory verticleFactory;
    private VerticleDiscoverer verticleDiscoverer;
    private static final Logger LOG = LoggerFactory.getLogger(MainVerticleLifecycle.class);
    private volatile int phase = Integer.MIN_VALUE + 10000;
    private volatile boolean isRunning = false;

    public MainVerticleLifecycle(Vertx vertx, VerticleFactory verticleFactory, VerticleDiscoverer verticleDiscoverer) {
        this.vertx = vertx;
        this.verticleFactory = verticleFactory;
        this.verticleDiscoverer = verticleDiscoverer;
    }

    @Override
    public void start() {
        vertx.registerVerticleFactory(verticleFactory);
        Collection<VerticleDefinition> verticles = verticleDiscoverer.findVerticles();
        for (VerticleDefinition verticleDefinition : verticles) {
            vertx.deployVerticle(verticleFactory.prefix() + ":" + verticleDefinition.getName(),verticleDefinition.getDeploymentOptions(),verticleDefinition.getHandler());
        }
        this.isRunning = true;
    }

    @Override
    public void stop() {
        vertx.close(res -> {
            if(res.succeeded()){
                this.isRunning = false;
                LOG.info("vertx关闭成功");
            }else{
                LOG.error("vertx关闭失败",res.cause());
                throw new IllegalStateException(res.cause());
            }
        });
    }

    @Override
    public boolean isRunning() {
        return this.isRunning;
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable callback) {
        stop();
        callback.run();
    }

    @Override
    public int getPhase() {
        return this.phase;
    }

}
